﻿#region Imports
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using CommonUtilities.Extensions;
using CommonUtilities.Properties;
#endregion

namespace CommonUtilities.Controls
{
    public partial class CUtil_TitleBar_Win : UserControl
    {
        private EventHandler minimizeToTray;
        public EventHandler MinimizeToTray
        {
            get { return minimizeToTray; }
            set { minimizeToTray = value; picMinimizeTray.Visible = !minimizeToTray.IsNull(); }
        }

        #region Declarations
        /// <summary>
        /// Colour mapper for Windows State buttons
        /// </summary>
        Dictionary<PictureBox, Color> colourMap = new Dictionary<PictureBox, Color>();

        /// <summary>
        /// Specifies if control dragging has started
        /// </summary>
        public Point m_DragStart;

        /// <summary>
        /// Specifies if control is being dragged
        /// </summary>
        public bool m_Dragging;

        /// <summary>
        /// Event to be fired before resizing parent window
        /// </summary>
        public event EventHandler PreResizeEvent;

        /// <summary>
        /// Event to be fired after resizing parent window
        /// </summary>
        public event EventHandler PostResizeEvent;
        #endregion

        #region Properties
        /// <summary>
        /// Parent window of the control
        /// </summary>
        public Form Parent { get; set; }

        /// <summary>
        /// Specifies if colours are to be used for different window states
        /// </summary>
        public bool UseStateColours { get; set; }

        private bool isMaximized;
        /// <summary>
        /// Specifies if parent window is maximized
        /// </summary>
        public bool IsMaximized
        {
            get { return isMaximized; }
            set { isMaximized = value; tltipWindowStates.SetToolTip(picMaximize, isMaximized ? "Restore Down" : "Maximize"); }
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new default instance of the CommonUtilities.Controls.CUtil_TitleBar class
        /// </summary>
        internal CUtil_TitleBar_Win()
        {
            MinimizeToTray = null;
        }

        /// <summary>
        /// Initializes a new instance of the CommonUtilities.Controls.CUtil_TitleBar class with asociated parent form
        /// </summary>
        /// <param name="parent">Parent form for the title bar</param>
        public CUtil_TitleBar_Win(Form parent)
            : this()
        {
            InitializeComponent();

            Parent = parent;
            // Parent.Resize += new EventHandler(Parent_Resize); // RKD
            Parent.TextChanged += new EventHandler(Parent_TextChanged);

            IsMaximized = (parent.WindowState == FormWindowState.Maximized);
        }
        #endregion

        #region Events
        private void Parent_TextChanged(object sender, EventArgs e)
        {
            lblTitle.Text = this.Text;
        }

        /// <summary>
        /// Occurs before the title bar becomes visible for the first time
        /// </summary>
        private void CUtil_TitleBar_Load(object sender, EventArgs e)
        {
            lblTitle.Text = Parent.Text;

            picIcon.BackColor = lblTitle.BackColor;

            if (Parent.Icon.IsNull()) lblTitle.Padding = new Padding(0);
            else picIcon.Image = Parent.Icon.ToBitmap();
            picMinimize.Image = Resources.Window_Minimize;
            picMaximize.Image = Resources.Window_Maximize;
            picClose.Image = Resources.Window_Close;

            colourMap.AddToDictionary(picMinimizeTray, Color.Yellow);
            colourMap.AddToDictionary(picMinimize, Color.Yellow);
            colourMap.AddToDictionary(picMaximize, Color.Chartreuse);
            colourMap.AddToDictionary(picClose, Color.FromArgb(255, 128, 128));
        }

        /// <summary>
        /// Occurs when the title bar is resized
        /// </summary>
        private void CUtil_TitleBar_Resize(object sender, EventArgs e)
        {
            this.Height = 26;
        }

        #region Animations
        /// <summary>
        /// Occurs when the mouse pointer enters the Window State modifiers
        /// </summary>
        private void picWindowState_MouseEnter(object sender, EventArgs e)
        {
            if (UseStateColours) colourMap._Where(elem => elem.Key == (PictureBox)sender)._ForEach(elem => elem.Key.BackColor = elem.Value);
        }

        /// <summary>
        /// Occurs when the mouse pointer leaves the Window State modifiers
        /// </summary>
        private void picWindowState_MouseLeave(object sender, EventArgs e)
        {
            if (UseStateColours) colourMap._Where(elem => elem.Key == (PictureBox)sender)._ForEach(elem => elem.Key.BackColor = Color.Transparent);
        }
        #endregion Animations

        #region Move on drag // http://social.msdn.microsoft.com/Forums/en-US/b4b833b4-fba8-4c20-9164-580d7249b0bf/how-to-use-dragmove
        /// <summary>
        /// Occurs when the mouse pointer is over the title bar and a mouse button is pressed
        /// </summary>
        private void lblTitle_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                m_DragStart = e.Location;
                m_Dragging = true;
            }
        }

        /// <summary>
        /// Occurs when the mouse pointer is moved over the title bar
        /// </summary>
        private void lblTitle_MouseMove(object sender, MouseEventArgs e)
        {
            if (m_Dragging && e.Button == MouseButtons.Left)
                Parent.Location += new Size(e.Location.X - m_DragStart.X, e.Location.Y - m_DragStart.Y);
        }

        /// <summary>
        /// Occurs when the mouse pointer is over the title bar and a mouse button is released
        /// </summary>
        private void lblTitle_MouseUp(object sender, MouseEventArgs e)
        {
            if (m_Dragging && e.Button == MouseButtons.Left) m_Dragging = false;
        }
        #endregion Move on drag

        #region Window states
        /// <summary>
        /// Occurs when window state Minimize modifier is pressed
        /// </summary>
        private void picMinimize_Click(object sender, EventArgs e)
        {
            Parent.WindowState = FormWindowState.Minimized;
        }

        /// <summary>
        /// Occurs when window state Maximize modifier is pressed
        /// </summary>
        private void picMaximize_Click(object sender, EventArgs e)
        {
            IsMaximized = !IsMaximized;
            Parent.WindowState = IsMaximized ? FormWindowState.Maximized : FormWindowState.Normal;
        }

        /// <summary>
        /// Occurs when window state Close modifier is pressed
        /// </summary>
        private void picClose_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
        #endregion Window states

        /// <summary>
        /// Occurs before the System.Windows.Forms.Control.KeyDown event when a key is pressed while focus is on this title bar
        /// </summary>
        private void CUtil_TitleBar_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (Form.ModifierKeys == Keys.Control || e.Modifiers == Keys.Control)
                if (e.KeyCode == Keys.Space)
                    picIcon_Click(sender, e);
        }
        #endregion

        #region Methods
        // RKD
        #endregion

        /// <summary>
        /// Occurs when title icon is clicked
        /// </summary>
        private void picIcon_Click(object sender, EventArgs e)
        {
            // Open context menu
            // RKD ctxtmnuTitleBar. = true
        }

        private void picMinimizeTray_Click(object sender, EventArgs e)
        {
            if (!MinimizeToTray.IsNull()) MinimizeToTray(sender, e);
        }
    }
}
